import { twoVnode } from "./react-dom";

// 批量更新实现
export const updateQueue = {
    isBatchData: false, // 表示是否同步更新
    updaters: [],
    batchUpdate() {
        // 
        updateQueue.updaters.forEach(up => up.updateComponent());
        updateQueue.isBatchData = false;
        updateQueue.updaters.length = 0; //重新置0
    }
};
class Updater {
    constructor(compInstance) {
        this.compInstance = compInstance; // 保存类的实例
        this.peddingState = []; // 保存数据, 合并批量更新
    }
    // 拿到数据，添加数据
    addState(partialState) {
        this.peddingState.push(partialState);
        // 更新
        this.emitUpdate();
    }

    emitUpdate() {
        // 判断一下是异步还是同步的
        if (updateQueue.isBatchData) {
            // 收集setState
            updateQueue.updaters.push(this);
        } else {
            // 更新组件
            this.updateComponent();
        }
    }
    updateComponent() {
        let { peddingState, compInstance } = this;
        // 获取到数据--->更新组件
        if (peddingState.length > 0) {
            sholdUpdate(compInstance, this.getState());
        }
    }
    // 获取到最新的数据
    getState() {
        let { peddingState, compInstance } = this;
        let { state } = compInstance; // 获取到最新的数据
        peddingState.forEach(nesState => {
            state = {
                ...state,
                ...nesState
            }
        });
        // console.log(state)
        // 清空数据
        peddingState = [];
        return state;
    }
}

/**
 * 1.初始化的使用
 * 2.更新的时候，通过render获取最新的vdom，再把vdom变成真实dom
 * 3.用新的真实dom替换旧的dom
 */
function sholdUpdate(compInstance, nextState) {
    compInstance.state = nextState;
    compInstance.forceUpdate();
}

class Component {
    static isReactComponent = true;
    constructor(props) {
        this.props = props;
        this.state = {};
        this.updater = new Updater(this);
    }
    setState(partialState) {
        // 更新的唯一途径
        this.updater.addState(partialState);
    }
    forceUpdate() {
        // 新的vnode
        let newVnode = this.render();
        let oldVnode = this.oldRenderVnode;
        let oldDom = oldVnode.dom;
        // console.log(oldDom)
        twoVnode(oldDom.parentNode, oldVnode, newVnode);
        // 重新将新的vnode保存到oldRenderVnode
        this.oldRenderVnode = newVnode;
    }
}


export default Component;